using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FiltronASP.Areas.Admin.ViewModels.Pages;
using FiltronASP.Areas.Admin.Consts;
using FiltronASP.Helpers.ActionFilters;
using FiltronASP.Helpers.FileUpload;
using FiltronASP.Helpers.Pagination;
using FiltronASP.Helpers.StringExtensions;
using FiltronASP.Models;
using FiltronASP.Models.DAO;
using FiltronASP.Models.DAO.Extensions;
using FiltronASP.Models.DAO.Interfaces;
using FiltronASP.Areas.Admin.Helpers.Permissions;

namespace FiltronASP.Areas.Admin.Controllers
{
    public class PagesController : BaseController
    {
        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela stron
        /// </summary>
        protected IPageDAO _pageDAO;

        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela szablonow
        /// </summary>
        protected ITemplateDAO _templateDAO;

        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela zmiennych
        /// </summary>
        protected IVariableDAO _variableDAO;

        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela wartosci zmiennych
        /// </summary>
        protected IVariableValueDAO _variableValueDAO;

        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela galerii
        /// </summary>
        protected IGalleryDAO _galleryDAO;

        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela obrazkow
        /// </summary>
        protected IGalleryImageDAO _galleryImageDAO;

        /// <summary>
        /// klasa odpowiedzialna za operacja na bazie danych, tabela pozycji w menu
        /// </summary>
        protected IMenuItemDAO _menuItemDAO;

        /// <summary>
        /// Konstruktor.
        /// </summary>
        /// <param name="pageDAO">klasa odpowiedzialna za operacja na bazie danych, tabela stron</param>
        /// <param name="templateDAO">klasa odpowiedzialna za operacja na bazie danych, tabela szablonow</param>
        /// <param name="pageTypeDAO">klasa odpowiedzialna za operacja na bazie danych, tabela grup stron</param>
        /// <param name="variableDAO">klasa odpowiedzialna za operacja na bazie danych, tabela zmiennych</param>
        /// <param name="variableValueDAO">klasa odpowiedzialna za operacja na bazie danych, tabela wartosci zmiennych</param>
        /// <param name="galleryDAO">klasa odpowiedzialna za operacja na bazie danych, tabela galerii</param>
        /// <param name="menuItemDAO">klasa odpowiedzialna za operacja na bazie danych, tabela pozycji w menu</param>
        /// <param name="galleryImageDAO">klasa odpowiedzialna za operacja na bazie danych, tabela obrazkow</param>
        public PagesController(IPageDAO pageDAO, ITemplateDAO templateDAO, IVariableDAO variableDAO,
            IVariableValueDAO variableValueDAO, IGalleryDAO galleryDAO, IMenuItemDAO menuItemDAO,
            IGalleryImageDAO galleryImageDAO) 
            : base()
        {
            this._pageDAO = pageDAO;
            this._templateDAO = templateDAO;
            this._variableDAO = variableDAO;
            this._variableValueDAO = variableValueDAO;
            this._galleryDAO = galleryDAO;
            this._menuItemDAO = menuItemDAO;
            this._galleryImageDAO = galleryImageDAO;
        }

        /// <summary>
        /// Konstruktor (dependency injection).
        /// </summary>
        public PagesController() 
            : this(new PageDAO(), new TemplateDAO(), new VariableDAO(), 
            new VariableValueDAO(), new GalleryDAO(), new MenuItemDAO(), 
            new GalleryImageDAO())
        {
        }

        /// <summary>
        /// Metoda pomocnicza do pobierania modelu <code>PagesIndexViewModel</code>.
        /// </summary>
        /// <param name="page">biezaca strona paginacji</param>
        /// <param name="pageTypeId">id biezacej grupy stron</param>
        /// <param name="currentLanguageId">id biezacej wersji jezykowej</param>
        /// <returns>odpowiedni model danych</returns>
        private PagesIndexViewModel GetPagesIndexViewModel(int? page, int? pageTypeId, int? currentLanguageId)
        {
            if (page == null)
            {
                page = 1;
            }   //if
            if (pageTypeId.HasValue)
            {
                return new PagesIndexViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        this.GetCurrentLanguage(currentLanguageId),
                        Pagination.ToPagedList<Page>(this._pageDAO.FindByPageType(pageTypeId.Value), page.Value), 
                        this.GetTemplatesToDropDown(null, pageTypeId, currentLanguageId), 
                        this.GetCurrentPageType(pageTypeId), 
                        page.Value);
            }   //if value
            else
            {
                return new PagesIndexViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        this.GetCurrentLanguage(currentLanguageId),
                        null, 
                        this.GetTemplatesToDropDown(null, null, currentLanguageId),
                        this.GetCurrentPageType(null), 
                        page.Value);
            }   //else value
        }

        /// <summary>
        /// Metoda pomocnicza do pobierania modelu <code>PagesIndexViewModel</code>.
        /// </summary>
        /// <param name="pageTypeId">id biezacej grupy stron</param>
        /// <param name="currentLanguageId">id biezacej wersji jezykowej</param>
        /// <returns>odpowiedni model danych</returns>
        private PagesIndexViewModel GetPagesIndexViewModel(int? pageTypeId, int? currentLanguageId)
        {
            if (pageTypeId.HasValue)
            {
                return new PagesIndexViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        this.GetCurrentLanguage(currentLanguageId),
                        Pagination.ToPagedList<Page>(this._pageDAO.FindByPageType(pageTypeId.Value), 1),
                        this.GetTemplatesToDropDown(null, pageTypeId, currentLanguageId),
                        this.GetCurrentPageType(pageTypeId));
            }   //if value
            else
            {
                return new PagesIndexViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        this.GetCurrentLanguage(currentLanguageId),
                        null,
                        this.GetTemplatesToDropDown(null, null, currentLanguageId),
                        this.GetCurrentPageType(null));
            }   //else value
        }

        /// <summary>
        /// Metoda pomocnicza do pobierania modelu <code>PagesIndexViewModel</code>.
        /// </summary>
        /// <param name="currentLanguageId">id biezacej wersji jezykowej</param>
        /// <returns>odpowiedni model danych</returns>
        private PagesIndexViewModel GetPagesIndexViewModel(int? currentLanguageId)
        {
            Language currentLanguage = this.GetCurrentLanguage(currentLanguageId);
            PageType currentPageType = this._pageTypeDAO.GetDefaultPageType(currentLanguage);
            if (currentPageType != null)
            {
                return new PagesIndexViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        this.GetCurrentLanguage(currentLanguageId),
                        Pagination.ToPagedList<Page>(this._pageDAO.FindByPageType(currentPageType.page_type_id), 1),
                        this.GetTemplatesToDropDown(null, currentPageType.page_type_id, currentLanguageId),
                        currentPageType);
            } else {    //if
                return new PagesIndexViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        currentLanguage);
            }   //else
        }

        /// <summary>
        /// Metoda pomocnicza do pobierania modelu <code>PagesEditionViewModel</code>.
        /// </summary>
        /// <param name="pageToOperateWith">biezaca strona</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>odpowiedni model danych</returns>
        private PagesEditionViewModel GetPagesEditionViewModel(Page pageToOperateWith, int? paginationPage)
        {
            if (paginationPage == null)
            {
                paginationPage = 1;
            }   //if null
            if (pageToOperateWith == null)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, pageToOperateWith object null...");
            }   //if null
            int? languageId = pageToOperateWith.language_id;
            int? pageTypeId = pageToOperateWith.page_type_id;
            int? templateId = pageToOperateWith.template_id;
            if (!languageId.HasValue)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, languageId null...");
            }   //if null
            if (!pageTypeId.HasValue)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, pageTypeId null...");
            }   //if null
            if (!templateId.HasValue)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, templateId null...");
            }   //if null
            return new PagesEditionViewModel(this.GetLanguagesToDropDown(languageId),
                        this.GetPageTypesInMenu(languageId),
                        this.GetMenus(languageId),
                        this.GetCurrentLanguage(languageId),
                        this.GetCurrentPageType(pageTypeId),
                        pageToOperateWith,
                        this.GetPageGalleries(templateId, languageId), 
                        this.GetPageVariables(templateId, languageId, PagesConsts.HTML_VARIABLE_TYPE_NAME), 
                        this.GetPageVariables(templateId, languageId, PagesConsts.TEXT_VARIABLE_TYPE_NAME), 
                        paginationPage.Value);
        }

        /// <summary>
        /// Metoda pomocnicza do pobierania modelu <code>PagesEditionViewModel</code>.
        /// </summary>
        /// <param name="pageToOperateWith">biezaca strona</param>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">grupa stron</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns></returns>
        private PagesEditionViewModel GetPagesEditionViewModel(Page pageToOperateWith, int? currentLanguageId,
            int? currentPageTypeId, int? paginationPage)
        {
            if (paginationPage == null)
            {
                paginationPage = 1;
            }   //if null
            if (pageToOperateWith == null)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, pageToOperateWith object null...");
            }   //if null
            int? templateId = pageToOperateWith.template_id;
            if (!currentLanguageId.HasValue)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, languageId null...");
            }   //if null
            if (!currentPageTypeId.HasValue)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, pageTypeId null...");
            }   //if null
            if (!templateId.HasValue)
            {
                throw new Exception("PagesController exception: GetPagesEditionViewModel method, templateId null...");
            }   //if null
            return new PagesEditionViewModel(this.GetLanguagesToDropDown(currentLanguageId),
                        this.GetPageTypesInMenu(currentLanguageId),
                        this.GetMenus(currentLanguageId),
                        this.GetCurrentLanguage(currentLanguageId),
                        this.GetCurrentPageType(currentPageTypeId),
                        pageToOperateWith,
                        this.GetPageGalleries(templateId, currentLanguageId),
                        this.GetPageVariables(templateId, currentLanguageId, PagesConsts.HTML_VARIABLE_TYPE_NAME),
                        this.GetPageVariables(templateId, currentLanguageId, PagesConsts.TEXT_VARIABLE_TYPE_NAME), 
                        paginationPage.Value);
        }

        /// <summary>
        /// Metoda pobierajaca szablony umieszczane w drop downie na gorze strony.
        /// </summary>
        /// <param name="selectedId">aktualnie wybrany szablon</param>
        /// <param name="currentLanguageId">aktualna wersja jezykowka</param>
        /// <param name="pageTypeId">aktualna grupa stron</param>
        /// <returns>szablony umieszczane w drop downie</returns>
        private IEnumerable<SelectListItem> GetTemplatesToDropDown(int? selectedId, int? pageTypeId, 
            int? currentLanguageId)
        {
            if ((!pageTypeId.HasValue) || (!currentLanguageId.HasValue))
            {
                return null;
            }   //if
            if (this._templateDAO == null)
            {
                return null;
            }   //if null
            IQueryable<Template> templates = this._templateDAO.FindByLangAndPageType(currentLanguageId.Value, 
                pageTypeId.Value);
            if (templates == null)
            {
                return null;
            }   //if null
            return templates.ToSelectListItems(selectedId);
        }

        /// <summary>
        /// Metoda pobierajaca aktualna grupe stron.
        /// </summary>
        /// <param name="pageTypeId">id aktualnej grupe stron</param>
        /// <returns>aktualna grupa stron</returns>
        private PageType GetCurrentPageType(int? pageTypeId)
        {
            if (!pageTypeId.HasValue)
            {
                return null;
            }   //if
            return this._pageTypeDAO.FindByPK(pageTypeId);
        }

        /// <summary>
        /// Metoda pobierajaca liste galerii dla szablonu i jezyka.
        /// </summary>
        /// <param name="templateId">szablon</param>
        /// <param name="languageId">wersja jezykowka</param>
        /// <returns>lista galerii dla strony</returns>
        private IQueryable<Gallery> GetPageGalleries(int? templateId, int? languageId)
        {
            if ((!templateId.HasValue) || (!languageId.HasValue))
            {
                Logger.MyLogger.Log("PagesController exception: GetPageGalleries method, templateId or languageId null object...");
                return null;
            }   //if
            if (this._galleryDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: GetPageGalleries method, galleryDAO null object...");
                return null;
            }   //if null
            return this._galleryDAO.FindByTemplateIdAndLanguageId(templateId.Value, languageId.Value);
        }

        /// <summary>
        /// Metoda pobierajaca liste zmiennych dla strony dla szablonu i jezyka.
        /// </summary>
        /// <param name="templateId">szablon</param>
        /// <param name="languageId">wersja jezykowka</param>
        /// <param name="varTypeName">typ zmiennej</param>
        /// <returns>lista zmiennych dla strony</returns>
        private IQueryable<Variable> GetPageVariables(int? templateId, int? languageId, string varTypeName)
        {
            if ((!templateId.HasValue) || (!languageId.HasValue))
            {
                Logger.MyLogger.Log("PagesController exception: GetPageVariables method, templateId or languageId null object...");
                return null;
            }   //if
            if (this._variableDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: GetPageVariables method, variableDAO null object...");
                return null;
            }   //if null
            return this._variableDAO.FindByTemplateAndTypeNameAndLanguage(templateId.Value, varTypeName, languageId.Value);
        }

        /// <summary>
        /// Akcja dla wyswietlania listy stron.
        /// </summary>
        /// <param name="page">biezaca strona paginacji</param>
        /// <param name="pageTypeId">aktualna grupa stron</param>
        /// <param name="currentLanguageId">aktualna wersja jezykowka</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult Index(int? page, int? pageTypeId, int? currentLanguageId)
        {
            if (page <= 0)
            {
                page = 1;
            }   //if
            Language currentLanguage = null;
            if (!currentLanguageId.HasValue)
            {
                currentLanguage = this._languageDAO.GetDefaultLanguage(this.GetAuthenticatedUserId());
                if (currentLanguage != null)
                {
                    currentLanguageId = currentLanguage.language_id;
                }   //if
            } else {   //if lang id null
                currentLanguage = this._languageDAO.FindByPK(currentLanguageId);
            }   //else lang id null
            if (!pageTypeId.HasValue)
            {
                PageType pageType = this._pageTypeDAO.GetDefaultPageType(currentLanguage);
                if (pageType != null)
                {
                    pageTypeId = pageType.page_type_id;
                }   //if
            }   //if page type id null
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), pageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            return View(this.GetPagesIndexViewModel(page, pageTypeId, currentLanguageId));
        }

        /// <summary>
        /// Metoda odpowiadajaca za operacje zmiany wersji jezykowej w drop downie.
        /// </summary>
        /// <param name="viewModel">model danych</param>
        /// <returns>odpowiedni widok</returns>
        [Authorize]
        public ActionResult ChangeLanguage(PagesIndexViewModel viewModel)
        {
            if (viewModel == null)
            {
                Logger.MyLogger.Log("PagesController exception: ChangeLanguage method, viewModel object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            return View("Index", this.GetPagesIndexViewModel(viewModel.DropDownLanguageId));
        }

        /// <summary>
        /// Tworzenie nowej strony.
        /// </summary>
        /// <param name="viewModel">model danych</param>
        /// <returns>widok</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [Authorize]
        public ActionResult Create(PagesIndexViewModel viewModel)
        {
            if (viewModel == null)
            {
                Logger.MyLogger.Log("PagesController exception: Create method, viewModel object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.CurrentLanguage == null)
            {
                Logger.MyLogger.Log("PagesController exception: Create method, viewModel.CurrentLanguage object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.CurrentPageType == null)
            {
                Logger.MyLogger.Log("PagesController exception: Create method, viewModel.CurrentPageType object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), viewModel.CurrentPageType.page_type_id))
            {
                return this.GetAccessDeniedView();
            }   //if
            Page newPage = this.GetNewPage(viewModel.CurrentPageType.page_type_id,
                viewModel.CurrentLanguage.language_id,
                viewModel.DropDownTemplateId);
            if (newPage == null)
            {
                Logger.MyLogger.Log("PagesController exception: Create method, new page object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (!this.InitVariableValues(newPage.page_id, 
                    viewModel.CurrentLanguage.language_id, 
                    viewModel.DropDownTemplateId))
            {
                Logger.MyLogger.Log("PagesController exception: Create method, cannot init variable values...");
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if not init
            return View(this.GetPagesEditionViewModel(newPage, viewModel.PaginationPage));
        }

        /// <summary>
        /// Metoda dodajaca nowa strone do bazy danych.
        /// </summary>
        /// <param name="pageTypeId">grupa stron</param>
        /// <param name="languageId">jezyk</param>
        /// <param name="templateId">szablon</param>
        /// <returns>obiekt strony</returns>
        private Page GetNewPage(int? pageTypeId, int? languageId, int? templateId)
        {
            try
            {
                if ((!pageTypeId.HasValue) || (!languageId.HasValue) || (!templateId.HasValue))
                {
                    Logger.MyLogger.Log("PagesController exception: GetNewPage method, pageTypeId, languageId or templateId null...");
                    return null;
                }   //if
                Page newPage = new Page();
                newPage.language_id = languageId;
                newPage.page_alias = PagesConsts.DEFAULT_PAGE_ALIAS;
                newPage.page_name = PagesConsts.DEFAULT_PAGE_NAME + " " + this.GetMaxPageId();
                newPage.page_link = this.GeneratePageLink(newPage);
                newPage.page_created = DateTime.Now;
                newPage.page_editable = true;
                newPage.page_keywords = GlobalConsts.CMS_INSTANCE_NAME;
                newPage.page_meta = GlobalConsts.CMS_INSTANCE_NAME;
                newPage.page_modified = DateTime.Now;
                newPage.page_ordering = this.GetMaxOrdering(pageTypeId.Value, languageId.Value) + 1;
                newPage.page_published = true;
                newPage.page_removable = true;
                newPage.page_type_id = pageTypeId;
                newPage.template_id = templateId;
                return this._pageDAO.Add(newPage);
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return null;
            }   //catch            
        }

        /// <summary>
        /// Metoda pobierajaca strone z bazy danych.
        /// </summary>
        /// <param name="pageId">grupa stron</param>
        /// <returns>obiekt strony</returns>
        private Page GetPage(int? pageId)
        {
            try
            {
                if (!pageId.HasValue)
                {
                    Logger.MyLogger.Log("PagesController exception: GetPageToEdit method, pageId null...");
                    return null;
                }   //if
                if (this._pageDAO == null)
                {
                    Logger.MyLogger.Log("PagesController exception: GetPageToEdit method, pageDAO null...");
                    return null;
                }   //if
                return this._pageDAO.FindByPK(pageId);
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return null;
            }   //catch            
        }

        /// <summary>
        /// Metoda inicjujaca wartosci dla zmiennych dla nowej strony.
        /// </summary>
        /// <param name="languageId">jezyk</param>
        /// <param name="templateId">szablon</param>
        /// <param name="pageId">strona</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private bool InitVariableValues(int? pageId, int? languageId, int? templateId)
        {
            if ((!languageId.HasValue) || (!templateId.HasValue) || (!pageId.HasValue))
            {
                Logger.MyLogger.Log("PagesController exception: GetNewPage method, pageTypeId, languageId, pageId or templateId null...");
                return false;
            }   //if
            IQueryable<Variable> variables = this._variableDAO.FindByTemplateAndLanguage(templateId.Value, languageId.Value);
            if (variables != null)
            {
                foreach (Variable variable in variables)
                {
                    VariableValue variableValue = new VariableValue();
                    variableValue.page_id = pageId.Value;
                    variableValue.variable_id = variable.variable_id;
                    variableValue.variable_value_created = DateTime.Now;
                    variableValue.variable_value_modified = DateTime.Now;
                    variableValue.variable_value_published = true;
                    variableValue.variable_value = PagesConsts.DEFAULT_VARIABLE_VALUE;
                    if (this._variableValueDAO.Add(variableValue) == null)
                    {
                        Logger.MyLogger.Log("PagesController exception: InitVariableValues method, unable to init variable values...");
                        return false;
                    }   //if null
                }   //foreach
            }   //if
            return true;
        }

        /// <summary>
        /// Metoda pobierajaca najwyzszy porzadek dla sortowania stron.
        /// </summary>
        /// <param name="pageTypeId">typ strony</param>
        /// <returns>najwyzszy porzadek dla sortowania stron</returns>
        private int GetMaxOrdering(int pageTypeId, int languageId)
        {
            if (this._pageDAO == null)
            {
                return 0;
            }   //if
            int? maxOrdering = this._pageDAO.SelectMaxPageOrdering(pageTypeId, languageId);
            if ((maxOrdering < 0) || (maxOrdering == null))
            {
                maxOrdering = 0;
            }   //if
            return maxOrdering.Value;
        }

        /// <summary>
        /// Metoda pobierajaca najwyzsze id dla stron.
        /// </summary>
        /// <returns>najwyzsze id dla stron</returns>
        private int GetMaxPageId()
        {
            if (this._pageDAO == null)
            {
                return 1;
            }   //if
            int? maxId = this._pageDAO.SelectMaxPageId();
            if (maxId == null)
            {
                return 1;
            }   //if
            return maxId.Value + 1;
        }

        /// <summary>
        /// Akcja do zapisu nowej strony.
        /// </summary>
        /// <returns>widok</returns>        /// <param name="viewModel">model danych</param>
        /// <param name="collection">parametry z forma</param>

        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateOnlyIncomingValues]
        [ValidateInput(false)]
        [Authorize]
        public ActionResult CreateNewPage(PagesEditionViewModel viewModel, FormCollection formParams)
        {
            if (viewModel == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.CurrentLanguage == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel.CurrentLanguage object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.PageToOperateWith == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel.PageToOperateWith object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (viewModel.CurrentPageType == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel.CurrentPageType object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), viewModel.CurrentPageType.page_type_id))
            {
                return this.GetAccessDeniedView();
            }   //if
            try
            {
                if (ModelState.IsValid)
                {
                    if (!this.AreDatabaseConstraintsValid(viewModel.PageToOperateWith))
                    {
                        return View("Create", this.GetPagesEditionViewModel(viewModel.PageToOperateWith, viewModel.CurrentLanguage.language_id, 
                            viewModel.CurrentPageType.page_type_id, viewModel.PaginationPage));
                    }   //if not constraints
                    if (!this.UpdatePage(viewModel.PageToOperateWith))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    if (!this.UpdateHtmlVariables(viewModel.PageToOperateWith.page_id, viewModel.PageToOperateWith.template_id, 
                        viewModel.CurrentLanguage.language_id, formParams))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    if (!this.UpdateTextVariables(viewModel.PageToOperateWith.page_id, viewModel.PageToOperateWith.template_id, 
                        viewModel.CurrentLanguage.language_id, formParams))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    if (!this.UpdatePageGalleries(viewModel.PageToOperateWith.page_id, viewModel.PageToOperateWith.template_id,
                        viewModel.CurrentLanguage.language_id, formParams))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    return View("Index", this.GetPagesIndexViewModel(viewModel.PaginationPage,
                        viewModel.CurrentPageType.page_type_id, viewModel.CurrentLanguage.language_id));
                }   //if
                return View("Create", this.GetPagesEditionViewModel(viewModel.PageToOperateWith, viewModel.CurrentLanguage.language_id, 
                    viewModel.CurrentPageType.page_type_id, viewModel.PaginationPage));
            }   //try
            catch (Exception ex)            
            {
                Logger.MyLogger.Log(ex);
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //catch
        }

        /// <summary>
        /// Metoda do generowania linka dla strony.
        /// </summary>
        /// <param name="page">strona</param>
        /// <returns>link</returns>
        private string GeneratePageLink(Page page)
        {
            if (page == null)
            {
                throw new Exception("PagesController exception: GeneratePageLink method, page object null...");
            }   //if null
            return String.Format("{0},{1}.html", this.GeneratePageAlias(page), page.page_id);
        }

        /// <summary>
        /// Metoda do generowania aliasu dla strony.
        /// </summary>
        /// <param name="page">strona</param>
        /// <returns>alias</returns>
        private string GeneratePageAlias(Page page)
        {
            if (page == null)
            {
                throw new Exception("PagesController exception: GeneratePageAlias method, page object null...");
            }   //if null
            return page.page_name.RemovePolishChars().RewriteToUrl();
        }

        /// <summary>
        /// Metoda do aktualizacji strony w bazie na podstawie zadania.
        /// </summary>
        /// <param name="pageFromRequest">strona z modelu danych z zadania</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private bool UpdatePage(Page pageFromRequest)
        {
            if (pageFromRequest == null)
            {
                return false;
            }   //if null
            Page pageToUpdate = this._pageDAO.FindByPK(pageFromRequest.page_id);
            if (pageToUpdate == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePage method, unable to find page to update...");
                return false;
            }   //if null
            pageToUpdate.page_alias = this.GeneratePageAlias(pageFromRequest);
            pageToUpdate.page_link = this.GeneratePageLink(pageFromRequest);
            pageToUpdate.page_name = pageFromRequest.page_name;
            pageToUpdate.page_meta = pageFromRequest.page_meta;
            pageToUpdate.page_keywords = pageFromRequest.page_keywords;
            return this._pageDAO.SubmitChanges();
        }

        /// <summary>
        /// Metoda do aktualizacji zmiennych zadanego typu.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="templateId">szablon</param>
        /// <param name="languageId">wersja jezykowa</param>
        /// <param name="varTypeName">typ zmiennej</param>
        /// <param name="varPrefix">prefix nazwy w formie</param>
        /// <param name="formParams">zmienne z posta</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private bool UpdatePageVariables(int? pageId, int? templateId, int? languageId, 
            string varTypeName, string varPrefix, FormCollection formParams)
        {
            if (formParams == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageVariables method, form params null object...");
                return false;
            }   //if
            if ((!templateId.HasValue) || (!languageId.HasValue) || (!pageId.HasValue))
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageVariables method, pageId, templateId or languageId null object...");
                return false;
            }   //if
            if (this._variableDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageVariables method, variableDAO null object...");
                return false;
            }   //if null
            if (this._variableValueDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageVariables method, variableValueDAO null object...");
                return false;
            }   //if null
            try
            {
                IQueryable<Variable> variables = this._variableDAO.FindByTemplateAndTypeNameAndLanguage(templateId.Value, varTypeName, languageId.Value);
                if (variables == null)
                {
                    return true;
                }   //if null
                foreach (Variable variable in variables)
                {
                    string newVariableValueContent = formParams.Get(varPrefix + variable.variable_id);
                    if (newVariableValueContent != null)
                    {
                        VariableValue variableValue = this._variableValueDAO.FindByVariableAndPage(variable.variable_id, pageId.Value);
                        variableValue.variable_value = newVariableValueContent;                        
                        if (!this._variableValueDAO.SubmitChanges())
                        {
                            Logger.MyLogger.Log("PagesController exception: UpdatePageVariables method, unable to commit variable value...");
                        }   //if
                    }   //if not null
                }   //foreach
            return true;
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda do aktualizacji zmiennych html.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="templateId">szablon</param>
        /// <param name="languageId">wersja jezykowa</param>
        /// <param name="formParams">zmienne z posta</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private bool UpdateHtmlVariables(int? pageId, int? templateId, int? languageId, FormCollection formParams)
        {
            return this.UpdatePageVariables(pageId, templateId, languageId, PagesConsts.HTML_VARIABLE_TYPE_NAME,
                PagesConsts.VARIABLE_HTML_VALUE_PREFIX, formParams);
        }

        /// <summary>
        /// Metoda do aktualizacji zmiennych tekstowych.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="templateId">szablon</param>
        /// <param name="languageId">wersja jezykowa</param>
        /// <param name="formParams">zmienne z posta</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private bool UpdateTextVariables(int? pageId, int? templateId, int? languageId, FormCollection formParams)
        {
            return this.UpdatePageVariables(pageId, templateId, languageId, PagesConsts.TEXT_VARIABLE_TYPE_NAME,
                PagesConsts.VARIABLE_TEXT_VALUE_PREFIX, formParams);
        }

        /// <summary>
        /// Metoda do aktualizacji zmiennych zadanego typu.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="templateId">szablon</param>
        /// <param name="languageId">wersja jezykowa</param>
        /// <param name="formParams">zmienne z posta</param>
        /// <returns>true, gdy sie uda, false wpp</returns>
        private bool UpdatePageGalleries(int? pageId, int? templateId, int? languageId, FormCollection formParams)
        {
            if (formParams == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageGalleries method, form params null object...");
                return false;
            }   //if
            if (!pageId.HasValue)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageGalleries method, pageId null object...");
                return false;
            }   //if
            if (this._galleryDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdatePageGalleries method, galleryDAO null object...");
                return false;
            }   //if null
            try
            {
                IQueryable<Gallery> galleries = this._galleryDAO.FindByTemplateIdAndLanguageId(templateId.Value, languageId.Value);
                if (galleries == null)
                {
                    return true;
                }   //if null
                foreach (Gallery gallery in galleries)
                {
                    string galleryImagesRequestParam = formParams.Get(PagesConsts.VARIABLE_PHOTO_VALUE_PREFIX + gallery.gallery_id);
                    if (!String.IsNullOrEmpty(galleryImagesRequestParam))
                    {
                        if (!this.UpdateGalleryImages(pageId, gallery.gallery_id, galleryImagesRequestParam))
                        {
                            Logger.MyLogger.Log("PagesController exception: UpdatePageGalleries method, unable to update gallery...");
                        }   //if
                    }   //if not null
                }   //foreach
                return true;
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Edycja strony.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToEditId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult EditPage(int? pageToEditId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: EditPage method, currentLanguageId object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (currentPageTypeId == null)
            {
                Logger.MyLogger.Log("PagesController exception: EditPage method, currentPageTypeId object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (pageToEditId == null)
            {
                Logger.MyLogger.Log("PagesController exception: EditPage method, pageToEditId object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            Page pageToEdit = this.GetPage(pageToEditId);
            if (pageToEdit == null)
            {
                Logger.MyLogger.Log("PagesController exception: EditPage method, new page object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            return View(this.GetPagesEditionViewModel(pageToEdit, paginationPage));
        }

        /// <summary>
        /// Akcja do zapisu zedytowanej strony.
        /// </summary>
        /// <param name="language_id">klucz glowny tabeli</param>
        /// <param name="collection">parametry z forma</param>
        /// <returns>widok</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateOnlyIncomingValues]
        [ValidateInput(false)]
        [Authorize]
        public ActionResult SubmitPage(PagesEditionViewModel viewModel, FormCollection formParams)
        {
            if (viewModel == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.CurrentLanguage == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel.CurrentLanguage object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.PageToOperateWith == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel.PageToOperateWith object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (viewModel.CurrentPageType == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateNewPage method, viewModel.CurrentPageType object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), viewModel.CurrentPageType.page_type_id))
            {
                return this.GetAccessDeniedView();
            }   //if
            try
            {
                if (ModelState.IsValid)
                {
                    if (!this.AreDatabaseConstraintsValid(viewModel.PageToOperateWith))
                    {
                        return View("Create", this.GetPagesEditionViewModel(viewModel.PageToOperateWith, viewModel.CurrentLanguage.language_id, 
                            viewModel.CurrentPageType.page_type_id, viewModel.PaginationPage));
                    }   //if not constraints
                    if (!this.UpdatePage(viewModel.PageToOperateWith))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    if (!this.UpdateHtmlVariables(viewModel.PageToOperateWith.page_id, viewModel.PageToOperateWith.template_id,
                        viewModel.CurrentLanguage.language_id, formParams))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    if (!this.UpdateTextVariables(viewModel.PageToOperateWith.page_id, viewModel.PageToOperateWith.template_id,
                        viewModel.CurrentLanguage.language_id, formParams))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    if (!this.UpdatePageGalleries(viewModel.PageToOperateWith.page_id, viewModel.PageToOperateWith.template_id,
                        viewModel.CurrentLanguage.language_id, formParams))
                    {
                        return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                    }   //if
                    return View("Index", this.GetPagesIndexViewModel(viewModel.PaginationPage, 
                        viewModel.CurrentPageType.page_type_id, viewModel.CurrentLanguage.language_id));
                }   //if
                return View("EditPage", this.GetPagesEditionViewModel(viewModel.PageToOperateWith, viewModel.CurrentLanguage.language_id,
                    viewModel.CurrentPageType.page_type_id, viewModel.PaginationPage));
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //catch
        }

        /// <summary>
        /// Ukrycie strony.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToHideId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult HidePage(int? pageToHideId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: HidePage method, currentLanguageId object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (currentPageTypeId == null)
            {
                Logger.MyLogger.Log("PagesController exception: HidePage method, currentPageTypeId object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (pageToHideId == null)
            {
                Logger.MyLogger.Log("PagesController exception: HidePage method, pageToHideId object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (!this.PublishOrUnpublishPage(pageToHideId))
            {
                Logger.MyLogger.Log("PagesController exception: PublishOrUnpublishMenuItems method, unable to commit page visibility info...");
                return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
            }   //if
            if (!this.PublishOrUnpublishMenuItems(pageToHideId))
            {
                Logger.MyLogger.Log("PagesController exception: PublishOrUnpublishMenuItems method, unable to commit menu items visibility info...");
                return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
            }   //if
            return View("Index", this.GetPagesIndexViewModel(paginationPage, currentPageTypeId, currentLanguageId));
        }

        /// <summary>
        /// Ukrycie strony.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToPublishId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult PublishPage(int? pageToPublishId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            return this.HidePage(pageToPublishId, currentPageTypeId, currentLanguageId, paginationPage);
        }

        /// <summary>
        /// Metoda do ukrywania/publikacji strony.
        /// </summary>
        /// <param name="pageId">id strony</param>
        private bool PublishOrUnpublishPage(int? pageId)
        {
            try
            {
                Page page = this.GetPage(pageId);
                if (page == null)
                {
                    Logger.MyLogger.Log("PagesController exception: PublishOrUnpublishPage method, new page object null...");
                    return false;
                }   //if null
                page.page_published = !page.page_published;
                return this._pageDAO.SubmitChanges();
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda do ukrywania/publikacji elementow w menu na podstawie strony.
        /// </summary>
        /// <param name="pageId">id strony</param>
        private bool PublishOrUnpublishMenuItems(int? pageId)
        {
            try
            {
                if (pageId == null)
                {
                    Logger.MyLogger.Log("PagesController exception: PublishOrUnpublishMenuItems method, pageId null...");
                    return false;
                }   //if null
                Page page = this.GetPage(pageId);
                if (page == null)
                {
                    Logger.MyLogger.Log("PagesController exception: PublishOrUnpublishPage method, new page object null...");
                    return false;
                }   //if null
                IQueryable<MenuItem> menuItems = this._menuItemDAO.FindByPageId(pageId.Value);
                if (menuItems != null)
                {
                    foreach (MenuItem menuItem in menuItems)
                    {
                        menuItem.item_published = page.page_published;
                        if (!this._menuItemDAO.SubmitChanges())
                        {
                            Logger.MyLogger.Log("PagesController exception: PublishOrUnpublishMenuItems method, unable to commit menu item published info...");
                        }   //if
                    }   //foreach
                }   //if
                return true;
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda sprawdzajaca czy sa pozycje w menu zalezne od wybranej strony.
        /// </summary>
        /// <param name="pageId">id strony</param>
        private bool HasPageDependentMenuItems(int? pageId)
        {
            try
            {
                if (pageId == null)
                {
                    Logger.MyLogger.Log("PagesController exception: HasPageDependentMenuItems method, pageId null...");
                    return false;
                }   //if null
                Page page = this.GetPage(pageId);
                if (page == null)
                {
                    Logger.MyLogger.Log("PagesController exception: HasPageDependentMenuItems method, page object null...");
                    return false;
                }   //if null
                return (this._menuItemDAO.FindByPageId(pageId.Value) != null);
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Usuniecie strony.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToDeleteId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult DeletePage(int? pageToDeleteId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeletePage method, currentLanguageId object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (currentPageTypeId == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeletePage method, currentPageTypeId object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if ((pageToDeleteId == null) || (pageToDeleteId <= 0))
            {
                Logger.MyLogger.Log("PagesController exception: DeletePage method, pageToDeleteId object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            try
            {
                Page page = this.GetPage(pageToDeleteId);
                if (page == null)
                {
                    Logger.MyLogger.Log("PagesController exception: DeletePage method, page object null...");
                    return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
                }   //if
                if (this.HasPageDependentMenuItems(pageToDeleteId))
                {
                    Logger.MyLogger.Log("PagesController warning: DeletePage method, page has dependent menu items...");
                    return View("Errors/PagesErrorAreMenuItemsDependent", this.GetBaseViewModel(currentLanguageId));
                }   //if
                return View(this.GetPagesEditionViewModel(page, currentLanguageId, currentPageTypeId, paginationPage));
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
            }   //catch
        }

        /// <summary>
        /// Metoda usuwaja strone (i jej zaleznosci).
        /// </summary>
        /// <param name="viewModel">model danych</param>
        /// <returns>odpowiedni widok</returns>
        [AcceptVerbs(HttpVerbs.Post)]
        [Authorize]
        public ActionResult DeleteConfirmed(PagesEditionViewModel viewModel)
        {
            if (viewModel == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteConfirmed method, viewModel object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.CurrentLanguage == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteConfirmed method, viewModel.CurrentLanguage object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.PageToOperateWith == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteConfirmed method, viewModel.PageToOperateWith object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (viewModel.CurrentPageType == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteConfirmed method, viewModel.CurrentPageType object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), viewModel.CurrentPageType.page_type_id))
            {
                return this.GetAccessDeniedView();
            }   //if
            try
            {
                Page page = this.GetPage(viewModel.PageToOperateWith.page_id);
                if (page == null)
                {
                    Logger.MyLogger.Log("PagesController exception: DeletePage method, page object null...");
                    return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                }   //if
                if (!this.DeleteGalleryImages(page.page_id))
                {
                    Logger.MyLogger.Log("PagesController exception: DeletePage method, unable to delete gallery images...");
                    return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                }   //if
                if (!this.DeleteVariableValues(page.page_id))
                {
                    Logger.MyLogger.Log("PagesController exception: DeletePage method, unable to delete gallery images...");
                    return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
                }   //if
                if (this._pageDAO.Delete(page.page_id))
                {
                    if (this._pageDAO.SubmitChanges())
                    {
                        return View("Index", this.GetPagesIndexViewModel(viewModel.PaginationPage, 
                            viewModel.CurrentPageType.page_type_id, 
                            viewModel.CurrentLanguage.language_id));
                    }   //if submit
                }   //if
                Logger.MyLogger.Log("PagesController exception: DeletePage method, unable to delete page...");
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //catch
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //catch
        }

        /// <summary>
        /// Metoda usuwajaca wartosci zmiennych dla strony.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <returns></returns>
        private bool DeleteVariableValues(int? pageId)
        {
            if (pageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteVariableValues method, pageId null...");
                return false;
            }   //if null
            if (this._variableValueDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteVariableValues method, variableValueDAO null...");
                return false;
            }   //if null
            try
            {
                this._variableValueDAO.DeleteByPage(pageId.Value);
                return true;
            }   //catch
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda usuwajaca obrazki dla strony.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <returns></returns>
        private bool DeleteGalleryImages(int? pageId)
        {
            if (pageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteGalleryImages method, pageId null...");
                return false;
            }   //if null
            if (this._galleryImageDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteGalleryImages method, galleryImageDAO null...");
                return false;
            }   //if null
            try
            {
                this._galleryImageDAO.DeleteByPage(pageId.Value);
                return true;
            }   //catch
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda usuwajaca obrazki z galerii dla strony.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="galleryId">id galerii</param>
        /// <returns></returns>
        private bool DeleteGalleryImages(int? pageId, int? galleryId)
        {
            if (pageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteGalleryImages method, pageId null...");
                return false;
            }   //if null
            if (galleryId == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteGalleryImages method, galleryId null...");
                return false;
            }   //if null
            if (this._galleryImageDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: DeleteGalleryImages method, galleryImageDAO null...");
                return false;
            }   //if null
            try
            {
                this._galleryImageDAO.DeleteByGalleryAndPage(galleryId.Value, pageId.Value);
                return true;
            }   //catch
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda tworzaca w bazie kolekcje obrazkow dla galerii na stronie.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="galleryId">id galerii</param>
        /// <param name="galleryImagesRequestParam">parametr zadania przechowujacy informacje nt. obrazkow</param>
        /// <returns></returns>
        private bool CreateGalleryImages(int? pageId, int? galleryId, string galleryImagesRequestParam)
        {
            if (pageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateGalleryImages method, pageId null...");
                return false;
            }   //if null
            if (galleryId == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateGalleryImages method, galleryId null...");
                return false;
            }   //if null
            if (String.IsNullOrEmpty(galleryImagesRequestParam))
            {
                Logger.MyLogger.Log("PagesController exception: CreateGalleryImages method, galleryImagesRequestParam null...");
                return false;
            }   //if null
            if (this._galleryImageDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: CreateGalleryImages method, galleryImageDAO null...");
                return false;
            }   //if null
            try
            {
                string[] imagesInfo = galleryImagesRequestParam.Split(UploadConsts.GALLERY_IMAGES_INFO_SEPARATOR);
                int imageOrder = 0;
                foreach (string imageInfo in imagesInfo)
                {
                    string[] imageParams = imageInfo.Split(UploadConsts.GALLERY_IMAGES_DETAILED_INFO_SEPARATOR);
                    if (imageParams.Count() == UploadConsts.IMAGE_PARAMS_ARRAY_LENGTH)
                    {
                        GalleryImage newImage = new GalleryImage();
                        newImage.gallery_image_created = DateTime.Now;
                        newImage.gallery_image_modified = DateTime.Now;
                        newImage.gallery_image_link = HttpUtility.UrlDecode(imageParams[UploadConsts.IMAGE_LINK_INDEX]);
                        newImage.gallery_image_info = HttpUtility.UrlDecode(imageParams[UploadConsts.IMAGE_TITLE_INDEX]);
                        newImage.gallery_image_ordering = imageOrder;
                        newImage.gallery_image_published = true;
                        newImage.gallery_id = galleryId;
                        newImage.page_id = pageId;
                        if (this._galleryImageDAO.Add(newImage) == null)
                        {
                            Logger.MyLogger.Log("PagesController exception: CreateGalleryImages method, unable to add new image to database...");
                            return false;
                        }   //if null
                        imageOrder++;
                    } //if                       
                }   //foreach
                return true;
            }   //catch
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return false;
            }   //catch
        }

        /// <summary>
        /// Metoda aktualizujaca w bazie kolekcje obrazkow dla galerii na stronie.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="galleryId">id galerii</param>
        /// <param name="galleryImagesRequestParam">parametr zadania przechowujacy informacje nt. obrazkow</param>
        /// <returns></returns>
        private bool UpdateGalleryImages(int? pageId, int? galleryId, string galleryImagesRequestParam)
        {
            if (pageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdateGalleryImages method, pageId null...");
                return false;
            }   //if null
            if (galleryId == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdateGalleryImages method, galleryId null...");
                return false;
            }   //if null
            if (String.IsNullOrEmpty(galleryImagesRequestParam))
            {
                Logger.MyLogger.Log("PagesController exception: UpdateGalleryImages method, galleryImagesRequestParam null...");
                return false;
            }   //if null
            if (this._galleryImageDAO == null)
            {
                Logger.MyLogger.Log("PagesController exception: UpdateGalleryImages method, galleryImageDAO null...");
                return false;
            }   //if null
            try
            {
                if (this.DeleteGalleryImages(pageId, galleryId))
                {
                    return this.CreateGalleryImages(pageId, galleryId, galleryImagesRequestParam);
                }   //if
            }   //catch
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
            }   //catch
            return false;
        }

        /// <summary>
        /// Przesuniecie strony.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <param name="newOrdering">nowy porzadek</param>
        /// <param name="oldOrdering">stary porzadek</param>
        /// <returns>widok</returns>
        private bool MovePage(int? pageId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage, 
            int oldOrdering, int newOrdering)
        {
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: MovePage method, currentLanguageId object null...");
                return false;
            }   //if null
            if (currentPageTypeId == null)
            {
                Logger.MyLogger.Log("PagesController exception: MovePage method, currentPageTypeId object null...");
                return false;
            }   //if null
            if (pageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: MovePage method, pageId object null...");
                return false;
            }   //if null
            return this._pageDAO.ReorderPages(oldOrdering, newOrdering, currentPageTypeId.Value, currentLanguageId.Value, pageId.Value);
        }

        /// <summary>
        /// Przesuniecie strony o jedno w gore.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToMoveId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult PageOneUp(int? pageToMoveId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageOneUp method, currentLanguageId object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            Page page = this.GetPage(pageToMoveId);
            if (page == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageOneUp method, page object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (this.MovePage(pageToMoveId, currentPageTypeId, currentLanguageId, paginationPage, 
                page.page_ordering, page.page_ordering - 1))
            {
                return View("Index", this.GetPagesIndexViewModel(paginationPage, currentPageTypeId, currentLanguageId));
            }   //if
            return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
        }

        /// <summary>
        /// Przesuniecie strony o jedno w dol.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToMoveId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult PageOneDown(int? pageToMoveId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageOneDown method, currentLanguageId object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            Page page = this.GetPage(pageToMoveId);
            if (page == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageOneDown method, page object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (this.MovePage(pageToMoveId, currentPageTypeId, currentLanguageId, paginationPage,
                page.page_ordering, page.page_ordering + 1))
            {
                return View("Index", this.GetPagesIndexViewModel(paginationPage, currentPageTypeId, currentLanguageId));
            }   //if
            return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
        }

        /// <summary>
        /// Przesuniecie strony na sama gore.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToMoveId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult PageTopUp(int? pageToMoveId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageTopUp method, currentLanguageId object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            Page page = this.GetPage(pageToMoveId);
            if (page == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageTopUp method, page object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (this.MovePage(pageToMoveId, currentPageTypeId, currentLanguageId, paginationPage,
                page.page_ordering, 0))
            {
                return View("Index", this.GetPagesIndexViewModel(paginationPage, currentPageTypeId, currentLanguageId));
            }   //if
            return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
        }

        /// <summary>
        /// Przesuniecie strony na sam dol.
        /// </summary>
        /// <param name="currentLanguageId">wersja jezykowa</param>
        /// <param name="currentPageTypeId">typ strony</param>
        /// <param name="pageToMoveId">id strony</param>
        /// <param name="paginationPage">strona w paginacji</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult PageBottomDown(int? pageToMoveId, int? currentPageTypeId, int? currentLanguageId, int? paginationPage)
        {
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), currentPageTypeId))
            {
                return this.GetAccessDeniedView();
            }   //if
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageBottomDown method, currentLanguageId object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            if (currentPageTypeId == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageBottomDown method, currentPageTypeId object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            Page page = this.GetPage(pageToMoveId);
            if (page == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageBottomDown method, page object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            if (this.MovePage(pageToMoveId, currentPageTypeId, currentLanguageId, paginationPage,
                page.page_ordering, this.GetMaxOrdering(currentPageTypeId.Value, currentLanguageId.Value)))
            {
                return View("Index", this.GetPagesIndexViewModel(paginationPage, currentPageTypeId, currentLanguageId));
            }   //if
            return View("Errors/PagesError", this.GetBaseViewModel(currentLanguageId));
        }

        /// <summary>
        /// Pokazanie strony wlasciwej.
        /// </summary>
        /// <param name="pageId">id strony</param>
        /// <param name="currentLanguageId">id jezyka</param>
        /// <returns>widok</returns>
        [Authorize]
        public ActionResult ShowPage(int? pageId, int? currentLanguageId)
        {
            if (currentLanguageId == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageBottomDown method, currentLanguageId object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            Page page = this.GetPage(pageId);
            if (page == null)
            {
                Logger.MyLogger.Log("PagesController exception: PageBottomDown method, page object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(currentLanguageId));
            }   //if null
            return RedirectToAction("Index", "CMS", new {pageId = (pageId), pageAlias = (page.page_alias), area = (String.Empty)});
        }
        
        /// <summary>
        /// Metoda walidujaca poprawnosc wprowadzanych danych pod katem indeksow bazodanowych.
        /// </summary>
        /// <param name="pageFromRequest">element do walidacji</param>
        /// <returns>true, gdy ok, false wpp</returns>
        private bool AreDatabaseConstraintsValid(Page pageFromRequest)
        {
            if (pageFromRequest == null)
            {
                Logger.MyLogger.Log("PagesController exception: AreDatabaseConstraintsValid method, page from request null...");
                return false;
            }   //if null
            Page pageInEdition = this._pageDAO.FindByPK(pageFromRequest.page_id);
            if (pageInEdition == null)
            {
                Logger.MyLogger.Log("PagesController exception: AreDatabaseConstraintsValid method, unable to find page to validate...");
                return false;
            }   //if null
            if (!this._pageDAO.IsPageAliasLinkAndLanguageUnique(pageInEdition.language_id,
                this.GeneratePageAlias(pageFromRequest), this.GeneratePageLink(pageFromRequest), 
                pageInEdition.page_id))
            {
                ModelState.AddModelError("PageToOperateWith.page_name", "Wprowadzona nazwa strony jest już zajęta dla wybranej wersji językowej.");
                return false;
            }   //if
            return true;
        }

        /// <summary>
        /// Metoda anulujaca akcje dodawania nowej strony. 
        /// </summary>
        /// <param name="viewModel">model danych</param>
        /// <returns>odpowiedni widok</returns>
        [Authorize]
        public ActionResult CancelNewPage(PagesEditionViewModel viewModel)
        {
            if (viewModel == null)
            {
                Logger.MyLogger.Log("PagesController exception: CancelNewPage method, viewModel object null...");
                return View("Errors/PagesError", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.CurrentLanguage == null)
            {
                Logger.MyLogger.Log("PagesController exception: CancelNewPage method, viewModel.CurrentLanguage object null...");
                return View("Errors/PagesErrorLanguageUndefined", this.GetBaseViewModel(null));
            }   //if null
            if (viewModel.PageToOperateWith == null)
            {
                Logger.MyLogger.Log("PagesController exception: CancelNewPage method, viewModel.PageToOperateWith object null...");
                return View("Errors/PagesErrorNoPageFound", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (viewModel.CurrentPageType == null)
            {
                Logger.MyLogger.Log("PagesController exception: CancelNewPage method, viewModel.CurrentPageType object null...");
                return View("Errors/PagesErrorPageTypeUndefined", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //if null
            if (!PermissionHelper.IsUserPageTypeAvailable(this.GetAuthenticatedUserId(), viewModel.CurrentPageType.page_type_id))
            {
                return this.GetAccessDeniedView();
            }   //if
            try
            {
                return this.DeleteConfirmed(viewModel);
            }   //try
            catch (Exception ex)
            {
                Logger.MyLogger.Log(ex);
                return View("Errors/PagesError", this.GetBaseViewModel(viewModel.CurrentLanguage.language_id));
            }   //catch
        }

    }
}
